﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Net;
using System.Windows.Forms;

namespace ImageUpload {
    public class FtpClient {
        private string ftpServerIP;
        private string ftpUserID;
        private string ftpPassword;
        private static FtpWebRequest reqFTP;

        public FtpClient(string ftpServerIP, string ftpUserID, string ftpPassword) {
            this.ftpServerIP = ftpServerIP;
            this.ftpUserID = ftpUserID;
            this.ftpPassword = ftpPassword;
            reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri("ftp://" + ftpServerIP + "/"));
            reqFTP.Credentials = new NetworkCredential(ftpUserID, ftpPassword);
        }

        public void Upload(string filename, string path) {
            FileInfo fileInf = new FileInfo(filename);
            string uri = "ftp://" + ftpServerIP + "/" + NormalizeUrl(path) + fileInf.Name;

            Uri url = new Uri(uri);
            if (!ValidateURL(url)) return;

            reqFTP = (FtpWebRequest)FtpWebRequest.Create(url);
            reqFTP.Credentials = new NetworkCredential(ftpUserID, ftpPassword);

            // By default KeepAlive is true, where the control connection is 
            // not closed after a command is executed.
            // reqFTP.KeepAlive = false;

            // Specify the command to be executed.
            reqFTP.Method = WebRequestMethods.Ftp.UploadFile;

            // Specify the data transfer type.
            reqFTP.UseBinary = true;

            // Notify the server about the size of the uploaded file
            reqFTP.ContentLength = fileInf.Length;

            try {

                FileStream stream = new FileStream(filename, FileMode.Open, FileAccess.Read);
                int bufferLength = 1024;
                byte[] buffer = new byte[bufferLength];
                reqFTP.ContentLength = fileInf.Length;
                int count = 0;

                Stream requestStream = reqFTP.GetRequestStream();
                while ((count = stream.Read(buffer, 0, buffer.Length)) > 0) {
                    requestStream.Write(buffer, 0, count);
                }
                requestStream.Close();
                stream.Close();

                FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
                // response.StatusDescription
                response.Close();


            }
            catch (Exception ex) {
                MessageBox.Show(ex.Message, "Upload Error");
            }
        }

        public void Download(string filePath, string fileName) {
            try {
                //filePath = <<The full path where the 
                //file is to be created. the>>, 
                //fileName = <<Name of the file to be createdNeed not 
                //name on FTP server. name name()>>
                FileStream outputStream = new FileStream(filePath + "\\" + fileName, FileMode.Create);

                reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri("ftp://" + ftpServerIP + "/" + fileName));
                reqFTP.Credentials = new NetworkCredential(ftpUserID, ftpPassword);
                reqFTP.Method = WebRequestMethods.Ftp.DownloadFile;
                reqFTP.UseBinary = true;
                FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
                Stream ftpStream = response.GetResponseStream();
                long cl = response.ContentLength;
                int bufferSize = 2048;
                int readCount;
                byte[] buffer = new byte[2048];

                readCount = ftpStream.Read(buffer, 0, bufferSize);
                while (readCount > 0) {
                    outputStream.Write(buffer, 0, readCount);
                    readCount = ftpStream.Read(buffer, 0, bufferSize);
                }

                ftpStream.Close();
                outputStream.Close();
                response.Close();
            }
            catch (Exception ex) {
                MessageBox.Show(ex.Message);
            }
        }

        public static string NormalizeUrl(string url) {
            if (url != null && !url.EndsWith("/")) url += "/";
            return url;
        }

        private bool ValidateURL(Uri url) {
            if (url.Scheme != Uri.UriSchemeFtp) {
                MessageBox.Show("not valid ftp url");
                return false;
            }
            return true;
        }

        public void Delete(string path) {
            try {
                Uri url = new Uri("ftp://" + ftpServerIP + "/" + path);
                if (!ValidateURL(url)) return;

                reqFTP = (FtpWebRequest)FtpWebRequest.Create(url);
                reqFTP.UseBinary = true;
                reqFTP.Method = WebRequestMethods.Ftp.DeleteFile;
                reqFTP.Credentials = new NetworkCredential(ftpUserID, ftpPassword);

                FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
                // Console.WriteLine("Delete status: {0}", response.StatusDescription);
                response.Close();
                // return true;
            }
            catch (Exception ex) {
                System.Windows.Forms.MessageBox.Show(ex.Message);
            }
        }

        public string[] GetFileList(string path, string criteria) {
            string[] downloadFiles;
            StringBuilder result = new StringBuilder();
            path = NormalizeUrl(path);
            try {
                reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri("ftp://" + ftpServerIP + "/" + path));
                reqFTP.UseBinary = true;
                reqFTP.Method = WebRequestMethods.Ftp.ListDirectory;
                reqFTP.Credentials = new NetworkCredential(ftpUserID, ftpPassword);
                WebResponse response = reqFTP.GetResponse();
                StreamReader reader = new StreamReader(response.GetResponseStream());

                string line = reader.ReadLine();
                while (line != null) {
                    result.Append(line);
                    result.Append("\n");
                    line = reader.ReadLine();
                }
                // to remove the trailing '\n'
                result.Remove(result.ToString().LastIndexOf('\n'), 1);
                reader.Close();
                response.Close();
                return result.ToString().Split('\n');
            }
            catch (Exception ex) {
                System.Windows.Forms.MessageBox.Show(ex.Message);
                downloadFiles = null;
                return downloadFiles;
            }
        }




    }
}
